package com.kx.center.service.impl;

import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kx.center.common.Cache;
import com.kx.center.common.Constant;
import com.kx.center.entity.StoreAppAccount;
import com.kx.center.entity.StoreInfo;
import com.kx.center.entity.Suggestion;
import com.kx.center.exception.AccountAlreadyExistsException;
import com.kx.center.mappers.ChannelMapper;
import com.kx.center.mappers.StoreAppAccountMapper;
import com.kx.center.service.StoreAppAccountService;
import com.kx.center.util.JpushUtil;
import com.kx.center.util.SHA1Coder;
import com.kx.center.util.SQLUtil;
import com.kx.center.util.Salts;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

/**
 * 
 * @description 门段端登录账户服务类
 * @version 1.0
 * @author Scott
 * @date 2015年12月17日 上午11:53:19
 */
@Service
public class StoreAppAccountServiceImp implements StoreAppAccountService {

	@Autowired
	StoreAppAccountMapper accountMapper;
	@Autowired
	ChannelMapper channelMapper;

	@SuppressWarnings("restriction")
	@Override
	public void createAccount(StoreAppAccount account) throws AccountAlreadyExistsException, GeneralSecurityException {
		if (account.getUserId() == null || account.getUserId() == "" || account.getPassword() == null
				|| account.getPassword() == "") {
			throw new NullPointerException();
		}

		if (this.accountMapper.findAccountByUserId(account.getUserId()) != null) {
			throw new AccountAlreadyExistsException();
		}
		// 使用salt进行加密
		byte[] salt = Salts.nextSalt();
		char[] plaintext = account.getPassword().toCharArray();
		byte[] chipertext = SHA1Coder.encrypt(plaintext, salt);

		account.setSalt(Base64.encode(salt));
		account.setPassword(Base64.encode(chipertext));

		accountMapper.createAccount(account);

		Cache.set(Cache.APPACCOUNT, account.getId(), account);
	}

	@SuppressWarnings("restriction")
	@Override
	public HashMap<String, Object> findUserByUserIdAndPassword(String userId, String password)
			throws GeneralSecurityException {

		StoreAppAccount appAccount = accountMapper.findAccountByUserId(userId);
		if (appAccount == null) {
			return null;
		}
		byte[] salt = Base64.decode(appAccount.getSalt());
		char[] plaintext = password.trim().toCharArray();
		byte[] ciphertext = SHA1Coder.encrypt(plaintext, salt);

		if (appAccount.getPassword().equals(Base64.encode(ciphertext))) {
			String token = UUID.randomUUID().toString().replaceAll("-", "");
			appAccount.setToken(token);
			// 查询门店信息
			StoreInfo storeInfo = findStoreInfoByStoreId(appAccount.getStoreInfoId());

			appAccount.setStoreId(storeInfo.getId());
			appAccount.setCompanyId(storeInfo.getCompanyId());
			appAccount.setStoreName(storeInfo.getStoreName());
			appAccount.setPushType(storeInfo.getPushType());
			appAccount.setPaymentType(storeInfo.getPaymentType());

			HashMap<String, Object> map = new HashMap<>();
			map.put("accountInfo", appAccount);
			// map.put("storeInfo", storeInfo);

			Cache.set(Cache.TOKEN, token, System.currentTimeMillis() / 1000 + Constant.APP_TOKEN_VALIDITY);
			Cache.set(Cache.APPACCOUNT, token, appAccount);

			updateAppAccount(appAccount);

			return map;
		}

		return null;
	}

	private StoreInfo findStoreInfoByStoreId(int storeInfoId) {

		return accountMapper.findStoreInfoByStoreId(storeInfoId);
	}

	private void updateAppAccount(StoreAppAccount appAccount) {
		accountMapper.updateAppAccount(appAccount);

	}

	@Override
	public void sendJpush(Integer id, String channel) {

		List<StoreAppAccount> list = accountMapper.findUserIdById(id);
		for (StoreAppAccount s : list) {
			String mobile = s.getUserId();
			try {
				JpushUtil.newOrderPush(mobile, channel);
			} catch (Exception e) {
				System.out.println(e);
			}
		}
	}

	@Override
	public List<StoreAppAccount> findStoreAppAccountList(int pageNum, int count, Map<String, Object> whereMap) {
		String order = "id desc";
		String limitStr = pageNum * count + "," + (count + 1);

		String where = "";
		where = SQLUtil.builWhere(whereMap);
		List<StoreAppAccount> accountList = accountMapper.findStoreAppAccountList(where, order, limitStr);

		if (accountList == null) {
			accountList = new ArrayList<StoreAppAccount>();
		}

		return accountList;
	}

	public StoreAppAccount findAccountByToken(String token) {
		return accountMapper.findAccountByToken(token);
	}

	@Override
	public List<StoreAppAccount> findAccountByStoreInfoId(Integer storeInfoId) {
		return accountMapper.findAccountByStoreInfoId(storeInfoId);
	}

	@Override
	public void activateAccount(String userId) {

		accountMapper.activateAccount(userId);
	}

	@SuppressWarnings("restriction")
	@Override
	public void updateAccount(StoreAppAccount account) {
		// 1.通过加密方式获取 加密后的密码 及对应的salt值

		try {

			if (account.getPassword() == null) {
				// 不修改密码 到数据库中查询原密码和salt值
				StoreAppAccount account2 = accountMapper.findAccountById(account.getId());
				account.setPassword(account2.getPassword());
				account.setSalt(account2.getSalt());
			} else {
				byte[] salt = Salts.nextSalt();
				char[] plaintext = account.getPassword().toCharArray();
				byte[] chipertext = SHA1Coder.encrypt(plaintext, salt);
				account.setSalt(Base64.encode(salt));
				account.setPassword(Base64.encode(chipertext));
			}

			// 2.修改信息
			accountMapper.updateAccount(account);
			;
		} catch (GeneralSecurityException e) {
			e.printStackTrace();
		}

	}

	@Override
	public void deleteAccount(int id) {

		accountMapper.deleteAccount(id);
	}

	@Override
	public List<HashMap<String, Object>> findStoreByCompany(int companyId) {

		return accountMapper.findStoreByCompany(companyId);
	}

	@SuppressWarnings("restriction")
	@Override
	public boolean checkOldPassword(String userId, String oldPassword) {
		// 根据用户id获取原密码及盐加密信息
		Map<String, Object> passwordAndSalt = accountMapper.getPasswordAndSaltByUserId(userId);
		String realPassword = passwordAndSalt.get("password").toString();

		byte[] salt = Base64.decode(passwordAndSalt.get("salt").toString());
		char[] plaintext = oldPassword.trim().toCharArray();
		byte[] ciphertext;
		try {
			ciphertext = SHA1Coder.encrypt(plaintext, salt);
			if (realPassword.equals(Base64.encode(ciphertext))) {
				// 原密码合法
				return true;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}

		return false;
	}

	@Override
	public void changePasswordByUserId(String userId, String newPassword) {
		// 修改密码
		// 使用salt进行加密
		StoreAppAccount account = new StoreAppAccount();
		byte[] salt = Salts.nextSalt();
		char[] plaintext = newPassword.toCharArray();
		byte[] chipertext;
		try {
			chipertext = SHA1Coder.encrypt(plaintext, salt);
			account.setSalt(Base64.encode(salt));
			account.setPassword(Base64.encode(chipertext));
			account.setUserId(userId);
			accountMapper.changePasswordByUserId(account);
		} catch (Exception e) {
			e.printStackTrace();
		}

		
	}

	@Override
	public List<StoreAppAccount> findAccountListByPage(int pageNow, int pageSize) {
		// 获取账户列表
		List<StoreAppAccount> accountList = accountMapper.findAccountList((pageNow -1)*pageSize ,pageSize);
		
		return accountList;
	}

	@Override
	public int findPageCount() {
		// 获取账户列表页数
		return accountMapper.findPageCount();
	}

}
